#ifndef __MY_DATA__
#define __MY_DATA__
#include"util.hpp"
#include<mysql/mysql.h>
#include<cstdlib>
#include<mutex>

namespace aod{
#define HOST "127.0.0.1"
#define USER "liujj"
#define PASS "123456"
#define SQL_NAME "aod_system"
#define INSERT_VIDEO "insert tb_video values(null,'%s','%s','%s','%s');"
#define UPDATE_VIDEO "update tb_video set name='%s',info='%s' where id=%d;"
#define DELETE_VIDEO "delete from tb_video where id=%d;"
#define SELECTALL_VIDEO "select * from tb_video;"
#define SELECTONE_VIDEO "select * from tb_video where id=%d;"
#define SELECTLIKE_VIDEO "select * from tb_video where name like '%%%s%%';"

//在mysql中%有特殊含义 这里相当于是 “%%s%”；相当于是个转义字符

    static MYSQL *MysqlInit()//初始化返回创建得句柄
    {
        MYSQL *mysql=mysql_init(NULL);
        if(mysql==NULL)
        {
            std::cout<<"init mysql failed"<<std::endl;
            return NULL;
        }
        if(mysql_real_connect(mysql,HOST,USER,PASS,SQL_NAME,0,NULL,0)==NULL)
        {
            mysql_close(mysql);
            std::cout<<"mysql connect failed"<<std::endl;
        }
        mysql_set_character_set(mysql,"utf8mb4");
        return mysql;
    }

    static void MysqlDestroy(MYSQL *mysql)//销毁mysql句柄
    {
        if(mysql!=NULL)
        {
            mysql_close(mysql);
        }
    }
    static bool MysqlQuery(MYSQL *mysql,const std::string &quary)//执行mysql语句
    {
        int ret=mysql_query(mysql,quary.c_str());
        if(ret!=0)
        {
            std::cout<<quary<<std::endl;
            std::cout<<mysql_error(mysql)<<std::endl;
            return false;
        }
        return true;
    }

    class TableVideo//数据库视频表得操作
    {
    private:
        std::mutex _mutex;
        MYSQL *_mysql;
    public:
        TableVideo()//初始化锁和句柄
        {
            _mysql=MysqlInit();
            if(_mysql==NULL)
            {
                exit(-1);
            }
        }
        ~TableVideo()//释放锁和句柄
        {
            MysqlDestroy(_mysql);
        }
        bool Insert(const Json::Value *video)//插入视频信息
        {
            //后期需要对插入得信息进行校验，不然容易出问题
            std::string sql;
            sql.resize(4096+(*video)["info"].asString().size());
            sprintf(&sql[0],INSERT_VIDEO,(*video)["name"].asCString(),(*video)["info"].asCString(),(*video)["video"].asCString(),(*video)["image"].asCString());
            return MysqlQuery(_mysql,sql);
        }
        bool Update(int id,const Json::Value& video)//更新视频信息
        {
            //后期需要对信息进行校验，不然容易出问题
            std::string sql;
            sql.resize(4096+video["info"].asString().size());
            sprintf(&sql[0],UPDATE_VIDEO,video["name"].asCString(),video["info"].asCString(),id);
            return MysqlQuery(_mysql,sql);
        }
        bool Delete(int id)//删除指定视频信息
        {
            //后期需要对信息进行校验，不然容易出问题
            char sql[1024]={0};
            sprintf(sql,DELETE_VIDEO,id);
            return MysqlQuery(_mysql,sql);
        }
        bool SelectAll(Json::Value *videos)//查找所有视频信息
        {


            _mutex.lock();//加锁,保护查询和保存结果到本地得过程
            bool ret=MysqlQuery(_mysql,SELECTALL_VIDEO);
            if(ret==false)
            {
                _mutex.unlock();
                return false;
            }


            MYSQL_RES *res=mysql_store_result(_mysql);
            if(res==NULL)
            {
                std::cout<<"store result error"<<std::endl;
                _mutex.unlock();
                return false;
            }
            _mutex.unlock();//解锁

            int num_rows=mysql_num_rows(res);

                std::cout<<num_rows<<std::endl;

            for(int i=0;i<num_rows;i++)
            {
                MYSQL_ROW row=mysql_fetch_row(res);
                Json::Value val;
                val["id"]=std::stoi(row[0]);
                val["name"]=row[1];
                val["info"]=row[2];
                val["video"]=row[3];
                val["image"]=row[4];
                videos->append(val);
            }
            mysql_free_result(res);
            return true;

        }
        bool SelectOne(int id,Json::Value *video)//查找指定视频信息
        {
            char sql[1024];
            sprintf(sql,SELECTONE_VIDEO,id);
            _mutex.lock();//加锁保护查询和保存结果到本地得过程
            bool ret=MysqlQuery(_mysql,sql);
            if(ret==false)
            {
                _mutex.unlock();
                return false;
            }
            MYSQL_RES *res=mysql_store_result(_mysql);
            if(res==NULL)
            {
                std::cout<<"store result error"<<std::endl;
                _mutex.unlock();
                return false;
            }
            _mutex.unlock();

            int num_row=mysql_num_rows(res);
            if(num_row!=1)
            {
                mysql_free_result(res);
                std::cout<<"have no date"<<std::endl;
                return false;
            }

            MYSQL_ROW row=mysql_fetch_row(res);
            (*video)["id"]=std::stoi(row[0]);
            (*video)["name"]=row[1];
            (*video)["info"]=row[2];
            (*video)["video"]=row[3];
            (*video)["image"]=row[4];
            mysql_free_result(res);
            return true;
        }
        bool SelectLike(const std::string &key,Json::Value *videos)//模糊查找
        {
            char sql[1024];
            sprintf(sql,SELECTLIKE_VIDEO,key.c_str());
            _mutex.lock();//加锁,保护查询和保存结果到本地得过程
            bool ret=MysqlQuery(_mysql,sql);
            if(ret==false)
            {
                _mutex.unlock();
                return false;
            }

            MYSQL_RES *res=mysql_store_result(_mysql);
            if(res==NULL)
            {
                _mutex.unlock();
                std::cout<<"get store result error"<<std::endl;
                return false;
            }
            _mutex.unlock();
            int num_rows=mysql_num_rows(res);
            for(int i=0;i<num_rows;i++)
            {
                MYSQL_ROW row=mysql_fetch_row(res);
                Json::Value video;
                video["id"]=std::stoi(row[0]);
                video["name"]=row[1];
                video["info"]=row[2];
                video["video"]=row[3];
                video["image"]=row[4];
                videos->append(video);
            }
            mysql_free_result(res);
            return true;
        }
    };
}


#endif

